/**
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.portlet.blackboardvcportlet.dao.impl;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Version;
import org.apache.commons.lang.Validate;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
import org.hibernate.annotations.Type;
import org.jasig.portlet.blackboardvcportlet.data.AccessType;
import org.jasig.portlet.blackboardvcportlet.data.Presentation;
import org.jasig.portlet.blackboardvcportlet.data.RecordingMode;
import org.jasig.portlet.blackboardvcportlet.data.Session;
import org.jasig.portlet.blackboardvcportlet.data.UserSessionUrl;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
@Entity
@Table(name = "VC2_SESSION")
@SequenceGenerator(
name="VC2_SESSION_GEN",
sequenceName="VC2_SESSION_SEQ",
allocationSize=10
)
@TableGenerator(
name="VC2_SESSION_GEN",
pkColumnValue="VC2_SESSION",
allocationSize=10
)
@NaturalIdCache
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class SessionImpl implements Session {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "VC2_SESSION_GEN")
@Column(name = "SESSION_ID", nullable = false)
private final long sessionId;
@Version
@Column(name = "ENTITY_VERSION", nullable = false)
private final long entityVersion;
@NaturalId
@Column(name="BB_SESSION_ID", nullable = false)
private final long bbSessionId;
@ManyToOne(targetEntity = ConferenceUserImpl.class, optional = false)
@JoinColumn(name = "CREATOR", nullable = false)
private final ConferenceUserImpl creator;
@ManyToOne(targetEntity = PresentationImpl.class)
@JoinColumn(name = "PRESENTATION", nullable = true)
private PresentationImpl presentation;
@Column(name="SESSION_NAME", nullable = false, length = 1000)
private String sessionName;
@Column(name="START_TIME", nullable = false)
@Type(type="dateTime")
private DateTime startTime;
@Column(name="END_TIME", nullable = false)
@Type(type="dateTime")
private DateTime endTime;
@Column(name="BOUNDARY_TIME", nullable = false)
private int boundaryTime;
@Column(name="ACCESS_TYPE", nullable = false)
@Enumerated(EnumType.STRING)
private AccessType accessType;
@Column(name="RECORDINGS", nullable = false)
private boolean recordings;
@Column(name="CHAIR_NOTES", length = 4000)
private String chairNotes;
@Column(name="NON_CHAIR_NOTES", length = 4000)
private String nonChairNotes;
private String launchUrl;
@ManyToMany(targetEntity = ConferenceUserImpl.class, fetch = FetchType.LAZY)
@JoinTable(name="VC2_SESSION_CHAIRS",
joinColumns= @JoinColumn(name="SESSION_ID"),
inverseJoinColumns=@JoinColumn(name="USER_ID")
)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<ConferenceUserImpl> chairs = new HashSet<ConferenceUserImpl>(0);
@ManyToMany(targetEntity = ConferenceUserImpl.class, fetch = FetchType.LAZY)
@JoinTable(name="VC2_SESSION_NONCHAIRS",
joinColumns= @JoinColumn(name="SESSION_ID"),
inverseJoinColumns=@JoinColumn(name="USER_ID")
)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<ConferenceUserImpl> nonChairs = new HashSet<ConferenceUserImpl>(0);
@ManyToMany(targetEntity = MultimediaImpl.class, fetch = FetchType.LAZY)
@JoinTable(name="VC2_SESSION_MULTIMEDIA",
joinColumns= @JoinColumn(name="SESSION_ID"),
inverseJoinColumns=@JoinColumn(name="MULTIMEDIA_ID")
)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<MultimediaImpl> multimedias = new HashSet<MultimediaImpl>(0);
@Column(name="OPEN_CHAIR", nullable = false)
private boolean openChair;
@Column(name="MUST_BE_SUPERVISED", nullable = false)
private boolean mustBeSupervised;
@Column(name="RECORDING_MODE", nullable = false)
@Enumerated(EnumType.STRING)
private RecordingMode recordingMode;
@Column(name="MAX_TALKERS", nullable = false)
private int maxTalkers;
@Column(name="MAX_CAMERAS", nullable = false)
private int maxCameras;
@Column(name="RAISE_HAND_ON_ENTER", nullable = false)
private boolean raiseHandOnEnter;
@Column(name="RESERVE_SEATS", nullable = false)
private int reserveSeats;
@Column(name="VERSION_ID", nullable = false)
private long versionId;
@Column(name="ALLOW_IN_SESSION_INVITES", nullable = false)
private boolean allowInSessionInvites = true;
@Column(name="HIDE_PARTICIPANT_NAMES", nullable = false)
private boolean hideParticipantNames = true;
@Column(name="PERMISSIONS_ON", nullable = false)
private boolean permissionsOn = false;
@Column(name="SECURE_SIGN_ON", nullable = false)
private boolean secureSignOn = false;
@Column(name="GUEST_URL", nullable = false, length = 4000)
private String guestUrl;
@Column(name="LAST_UPDATED", nullable = false)
@Type(type = "dateTime")
private DateTime lastUpdated;
@OneToMany(mappedBy = "session", targetEntity = SessionRecordingImpl.class, cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<SessionRecordingImpl> sessionRecordings = new HashSet<SessionRecordingImpl>(0);
//Really a onetoone but blackboard treats it like a one to many
@OneToMany(mappedBy = "session", targetEntity = SessionTelephonyImpl.class, cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<SessionTelephonyImpl> sessionTelephony = new HashSet<SessionTelephonyImpl>(0);
//Exists only to allow cascading deletes, should NEVER be accessed by normal code
@OneToMany(mappedBy = "session", targetEntity = UserSessionUrlImpl.class, cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true)
private final Set<UserSessionUrl> userUrls = new HashSet<UserSessionUrl>(0);
/**
* needed by hibernate
*/
@SuppressWarnings("unused")
private SessionImpl() {
this.sessionId = -1;
this.entityVersion = -1;
this.bbSessionId = -1;
this.creator = null;
}
SessionImpl(long bbSessionId, ConferenceUserImpl creator) {
Validate.notNull(creator, "creator cannot be null");
this.sessionId = -1;
this.entityVersion = -1;
this.bbSessionId = bbSessionId;
this.creator = creator;
}
/**
* Used to keep lastUpdated up to date
*/
@PreUpdate
@PrePersist
protected final void onUpdate() {
lastUpdated = DateTime.now();
}
@Override
public boolean isPermissionsOn() {
return this.permissionsOn;
}
public void setPermissionsOn(boolean permissionsOn) {
this.permissionsOn = permissionsOn;
}
@Override
public boolean isSecureSignOn() {
return this.secureSignOn;
}
public void setSecureSignOn(boolean secureSignOn) {
this.secureSignOn = secureSignOn;
}
@Override
public String getSessionName() {
return sessionName;
}
public void setSessionName(String sessionName) {
this.sessionName = sessionName;
}
@Override
public DateTime getStartTime() {
return startTime;
}
public DateTime getStartTimeWithBoundaryTime () {
return startTime.minusMinutes(boundaryTime);
}
public void setStartTime(DateTime startTime) {
this.startTime = startTime;
}
public DateTime getEndTime() {
return endTime;
}
public void setEndTime(DateTime endTime) {
this.endTime = endTime;
}
@Override
public int getBoundaryTime() {
return boundaryTime;
}
public void setBoundaryTime(int boundaryTime) {
this.boundaryTime = boundaryTime;
}
@Override
public AccessType getAccessType() {
return accessType;
}
public void setAccessType(AccessType accessType) {
this.accessType = accessType;
}
@Override
public boolean isRecordings() {
return recordings;
}
public void setRecordings(boolean recordings) {
this.recordings = recordings;
}
@Override
public String getChairNotes() {
return chairNotes;
}
public void setChairNotes(String chairNotes) {
this.chairNotes = chairNotes;
}
@Override
public String getNonChairNotes() {
return nonChairNotes;
}
public void setNonChairNotes(String nonChairNotes) {
this.nonChairNotes = nonChairNotes;
}
Set<ConferenceUserImpl> getChairs() {
return chairs;
}
Set<ConferenceUserImpl> getNonChairs() {
return nonChairs;
}
Set<MultimediaImpl> getMultimedias() {
return multimedias;
}
Set<SessionRecordingImpl> getSessionRecordings() {
return sessionRecordings;
}
Set<SessionTelephonyImpl> getSessionTelephony() {
return sessionTelephony;
}
@Override
public DateTime getLastUpdated() {
return lastUpdated;
}
@Override
public boolean isOpenChair() {
return openChair;
}
public void setOpenChair(boolean openChair) {
this.openChair = openChair;
}
@Override
public boolean isMustBeSupervised() {
return mustBeSupervised;
}
public void setMustBeSupervised(boolean mustBeSupervised) {
this.mustBeSupervised = mustBeSupervised;
}
@Override
public RecordingMode getRecordingMode() {
return recordingMode;
}
public void setRecordingMode(RecordingMode recordingMode) {
this.recordingMode = recordingMode;
}
@Override
public int getMaxTalkers() {
return maxTalkers;
}
public void setMaxTalkers(int maxTalkers) {
this.maxTalkers = maxTalkers;
}
public int getMaxCameras() {
return maxCameras;
}
public void setMaxCameras(int maxCameras) {
this.maxCameras = maxCameras;
}
@Override
public boolean isRaiseHandOnEnter() {
return raiseHandOnEnter;
}
public void setRaiseHandOnEnter(boolean raiseHandOnEnter) {
this.raiseHandOnEnter = raiseHandOnEnter;
}
@Override
public int getReserveSeats() {
return reserveSeats;
}
public void setReserveSeats(int reserveSeats) {
this.reserveSeats = reserveSeats;
}
@Override
public long getVersionId() {
return versionId;
}
public void setVersionId(long versionId) {
this.versionId = versionId;
}
@Override
public boolean isAllowInSessionInvites() {
return allowInSessionInvites;
}
public void setAllowInSessionInvites(boolean allowInSessionInvites) {
this.allowInSessionInvites = allowInSessionInvites;
}
@Override
public boolean isHideParticipantNames() {
return hideParticipantNames;
}
public void setHideParticipantNames(boolean hideParticipantNames) {
this.hideParticipantNames = hideParticipantNames;
}
@Override
public String getGuestUrl() {
return guestUrl;
}
public void setGuestUrl(String guestUrl) {
this.guestUrl = guestUrl;
}
@Override
public long getSessionId() {
return sessionId;
}
@Override
public long getEntityVersion() {
return entityVersion;
}
@Override
public long getBbSessionId() {
return bbSessionId;
}
@Override
public ConferenceUserImpl getCreator() {
return creator;
}
@Override
public Presentation getPresentation() {
return presentation;
}
void setPresentation(PresentationImpl value) {
this.presentation = value;
}
@Override
public void setLaunchUrl(String launchUrl) {
this.launchUrl = launchUrl;
}
@Override
public String getLaunchUrl() {
return launchUrl;
}
@Override
public String getTimeFancyText(DateTime from, DateTime to) {
final String prefix = "Join in ";
if(to != null) {
Duration d = new Duration(to, from);
Period timeUntil = new Period(to.toInstant(),from.toInstant(), PeriodType.dayTime());
long standardDays = d.getStandardDays();
if(standardDays > 0) {
PeriodFormatter daysHours = new PeriodFormatterBuilder()
.appendDays()
.appendSuffix(" day", " days")
.appendSeparator(", and ")
.appendHours()
.appendSuffix(" hour", " hours")
.toFormatter();
return prefix + daysHours.print(timeUntil.normalizedStandard(PeriodType.dayTime()));
} else {
PeriodFormatter dafaultFormatter = new PeriodFormatterBuilder()
.appendHours()
.appendSuffix(" hour", " hours")
.appendSeparator(", and ")
.appendMinutes()
.appendSuffix(" minute", " minutes")
.toFormatter();
return prefix + dafaultFormatter.print(timeUntil.normalizedStandard(PeriodType.dayTime()));
}
} else {
return null;
}
}
@Override
public String getTimeUntilJoin() {
return getTimeFancyText(startTime, DateTime.now());
}
@Override
public String toString() {
return "BlackboardSessionImpl [sessionId=" + sessionId + ", sessionName=" + sessionName + ", startTime=" + startTime + ", endTime=" + endTime + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (bbSessionId ^ (bbSessionId >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SessionImpl other = (SessionImpl) obj;
if (bbSessionId != other.bbSessionId)
return false;
return true;
}
}